package cn.datawin.cmppprovider.task;

import cn.datawin.cmppprovider.pool.ExecutePoolService;
import cn.datawin.cmppprovider.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class DelayQueueManager implements CommandLineRunner {
    AtomicInteger atomicInteger ;
    List<DelayQueue<DelayTask>> queueList;
    int threadNum = 500;
    ExecutorService executorService ;
    @Override
    public void run(String... strings) throws Exception {
        executorService= Executors.newFixedThreadPool(threadNum);
        atomicInteger = new AtomicInteger();
        queueList = new ArrayList<>();
        for (int i = 0; i < threadNum; i++) {
            queueList.add(new DelayQueue<>());
            int finalI = i;
            executorService.submit(new Callable<Object>() {
                void run(){
                    while (true) {
                        try {
                            DelayTask task = queueList.get(finalI).take();
                            SpringContextUtil.getBean(ExecutePoolService.class).submit(() -> {
                                task.deal();
                                return null;
                            });
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

                @Override
                public Object call() throws Exception {
                    run();
                    return null;
                }
            });
        }
    }

    public void put(DelayTask task) {
        int andIncrement = atomicInteger.getAndIncrement();
        queueList.get(andIncrement%threadNum).put(task);
    }
}